-
Notifications
You must be signed in to change notification settings - Fork 14.1k
Change aarch64-unknown-none to generate static-PIE binaries by default
#149622
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Change aarch64-unknown-none to generate static-PIE binaries by default
#149622
Conversation
|
These commits modify compiler targets. |
|
r? @chenyukang rustbot has assigned @chenyukang. Use |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems sensible to me if target maintainers are on board. Feel free to r=me if so.
|
(Holding off on tagging this with relnotes in case target maintainers don't want to make this change.) |
|
Should the same change be made to aarch64-unknown-none-softfloat too? |
This comment has been minimized.
This comment has been minimized.
|
If this is to be done, it should be done to I assume the goal is compiling libcore PIE by default? (Otherwise for user programs I guess I'm not sure who this might affect: let me add it to the agenda for the REWG Meeting next Tuesday if that's OK and we'll take it from there once I've discussed it with folks. I think it shouldn't hurt users who are currently using static executables, apart from maybe minor code size impact (one way or the other)? |
|
@rustbot blocked (on target maintainers having a discussion) |
|
On the REWG agenda for next week. |
|
I have concerns here about who is going to setup/adjust the Global Offset Table that PIE will introduce. Let me go and ping the RustedFirmware-A maintainers, who use this target, and the Ferrocene people, who qualify (and test) this target for safety-critical use-cases. |
You can still tell the linker to produce a static executable I think, in which case the GOT would be statically initialized. And linker relaxation may even get rid of part of the GOT accesses entirely. If you don't change anything and let it produce a static-PIE executable, I believe the GOT is statically initialized to the value it would need to have if you load the executable at the same place as indicated in the ELF file (aka the relocation slide is 0). If you actually take advantage of the ability to relocate the executable at runtime, then you will need to write a loader that applies the GOT relocations. This could be the bootloader or inline assembly linked into the executable itself that is used as entrypoint. Or if you are very careful and don't mind the UB, you can write the relocation code in rust too. https://github.com/sunfishcode/origin/blob/main/src/relocate.rs |
|
So, it looks like this change would add a new So worst case, programs get larger. But to be honest, AArch64 machines often have quite a lot of memory. |
|
A few questions to help me understand the impact on RF-A and projects like it. Assuming we control code generation for the entire program, and that we do not explicitly enable PIC for any part of it:
@thejpster Ehh... they tend to have quite a lot of DRAM, but SRAM is a different story. |
|
It looks like Rust for Linux already passes cc @ojeda |
|
Does passing that option require build-std? |
+1, we do, unconditionally. |
|
@CJKay AFAIK:
For the PLT in particular however, the linker should be able to replace all PLT calls with direct calls for symbols that are neither exported nor imported as would probably be the case for your average kernel. Replacing PLT calls with direct calls doesn't require rewriting instructions, only changing the target address of PLT call relocations. Replacing GOT accesses however does require rewriting instructions. In a bunch of cases linker relaxations should be possible, but I don't know if it covers all GOT accesses. And it is probably going to depend on the exact linker version and compiler version. If you discard the GOT or PLT section while there are references to it I think you get a linker error, but it may also be just a warning (which rustc discards). |
|
Thanks, @bjorn3. I'm curious about (3) and (4):
How is it that we can ignore the GOT in this case? Wouldn't that leave it with relative addresses? Doesn't its very presence indicate that there are symbol references which need relocating? |
If you load the ELF file with an ASLR slide of 0 like you would have needed to do currently due to the static relocation model, then you don't need to apply relocations as the linker already put the correct values everywhere. Only when you use a non-zero ASLR slide do you need to actually apply relocations. But before this PR you wouldn't be able to use a non-zero ASLR slide anyway. |
Currently, `aarch64-unknown-none` generates static position *dependent* binaries which must be loaded at a fixed address in memory. The [openVMM](https://github.com/microsoft/openvmm) project uses the `*-unknown-none` targets for an embedded-like environment but needs the binary to be loadable to any memory address. Currently, the `x86_64-unknown-none` target is configured to allow this by default but the `aarch64-unknown-none` target is not. This commit changes the defaults for the `aarch64-unknown-none` target to enable static-PIE binaries which aligns the target more closely with the corresponding `x86_64-unknown-none` target. If users prefer the prior behavior, they can request that via `-Crelocation-model=static`.
a4cd181 to
e5212e6
Compare
|
@BartMassey and @jonathanpallant, I appreciate you pinging the various maintainers! I agree that Thanks @bjorn3 for answering those questions! I've updated this PR to make the same change to |
Understood, thanks. I have a couple of concerns with this:
I don't think there's a satisfactory answer to this right now; either everybody is limited to static relocation, or everybody pays the penalty of a GOT. The firmware ecosystem can maybe stomach the overhead until |
I wasn't aware of that.
If you use |
It isn't particularly uncommon to discard the GOT altogether. That may be a case of "holding it wrong", but it's worth knowing that there are projects out there that will break after this change - they will need a heads-up. |
Currently,
aarch64-unknown-nonegenerates static position dependent binaries which must be loaded at a fixed address in memory. The openVMM project uses the*-unknown-nonetargets for an embedded-like environment but needs the binary to be loadable to any memory address. Currently, thex86_64-unknown-nonetarget is configured to allow this by default but theaarch64-unknown-nonetarget is not.This commit changes the defaults for the
aarch64-unknown-nonetarget to enable static-PIE binaries which aligns the target more closely with the correspondingx86_64-unknown-nonetarget. If users prefer the prior behavior, they can request that via-Crelocation-model=static.cc @BartMassey as lead maintainer for this target in REWG